<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Agent 流式输出演示</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        
        .container {
            background: white;
            border-radius: 10px;
            padding: 30px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        h1 {
            color: #333;
            text-align: center;
            margin-bottom: 30px;
        }
        
        .input-section {
            margin-bottom: 30px;
        }
        
        textarea {
            width: 100%;
            height: 100px;
            padding: 15px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            resize: vertical;
            box-sizing: border-box;
        }
        
        textarea:focus {
            outline: none;
            border-color: #4CAF50;
        }
        
        .button-group {
            display: flex;
            gap: 10px;
            margin-top: 15px;
        }
        
        button {
            flex: 1;
            padding: 12px 24px;
            border: none;
            border-radius: 6px;
            font-size: 16px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        
        .btn-primary {
            background-color: #4CAF50;
            color: white;
        }
        
        .btn-primary:hover {
            background-color: #45a049;
        }
        
        .btn-secondary {
            background-color: #2196F3;
            color: white;
        }
        
        .btn-secondary:hover {
            background-color: #1976D2;
        }
        
        .btn-danger {
            background-color: #f44336;
            color: white;
        }
        
        .btn-danger:hover {
            background-color: #d32f2f;
        }
        
        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        
        .output-section {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-top: 30px;
        }
        
        .output-box {
            border: 2px solid #ddd;
            border-radius: 8px;
            padding: 20px;
            background-color: #fafafa;
            min-height: 300px;
        }
        
        .output-box h3 {
            margin-top: 0;
            color: #555;
            border-bottom: 2px solid #eee;
            padding-bottom: 10px;
        }
        
        .output-content {
            font-family: 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.6;
            white-space: pre-wrap;
            word-wrap: break-word;
            max-height: 400px;
            overflow-y: auto;
            min-height: 300px;
        }
        
        .thinking {
            color: #666;
            font-style: italic;
            white-space: pre-wrap; /* 确保思考过程内容正确换行 */
            word-wrap: break-word;
        }
        
        .answer {
            color: #333;
            font-weight: normal;
            white-space: pre-wrap; /* 确保答案内容正确换行 */
            word-wrap: break-word;
        }
        
        .error {
            color: #d32f2f;
            font-weight: bold;
            white-space: pre-wrap; /* 确保错误信息正确换行 */
            word-wrap: break-word;
        }
        
        .status {
            background-color: #e3f2fd;
            border: 1px solid #2196F3;
            border-radius: 4px;
            padding: 10px;
            margin-bottom: 20px;
            text-align: center;
            font-weight: bold;
        }
        
        .loading {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid #f3f3f3;
            border-top: 3px solid #3498db;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-right: 10px;
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .clear-btn {
            background-color: #FF9800;
            color: white;
            margin-top: 20px;
        }
        
        .clear-btn:hover {
            background-color: #F57C00;
        }
        
        @media (max-width: 768px) {
            .output-section {
                grid-template-columns: 1fr;
            }
            
            .button-group {
                flex-direction: column;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🤖 AI Agent 流式输出演示</h1>
        
        <div class="status" id="status">
            准备就绪，请输入任务描述
        </div>
        
        <div class="input-section">
            <textarea id="taskInput" placeholder="请输入您希望AI执行的任务，例如：&#10;&#10;1. 分析一个Java文件的代码质量&#10;2. 生成一个Python脚本来处理数据&#10;3. 创建一个简单的Web应用"></textarea>
            
            <div class="button-group">
                <button class="btn-primary" onclick="executeStream()" id="streamBtn">
                    🚀 流式输出 (SSE)
                </button>
                <button class="btn-secondary" onclick="executeFlux()" id="fluxBtn">
                    ⚡ 简化流式 (Flux)
                </button>
                <button class="btn-danger" onclick="executeNormal()" id="normalBtn">
                    📋 传统方式
                </button>
            </div>
        </div>
        
        <div class="output-section">
            <div class="output-box">
                <h3>🧠 思考过程</h3>
                <div id="thinkingOutput" class="output-content"></div>
            </div>
            
            <div class="output-box">
                <h3>💬 最终答案</h3>
                <div id="answerOutput" class="output-content"></div>
            </div>
        </div>
        
        <button class="clear-btn" onclick="clearOutputs()">🗑️ 清空输出</button>
    </div>

    <script>
        let currentEventSource = null;
        let isThinking = true;

        function updateStatus(message, isLoading = false) {
            const statusEl = document.getElementById('status');
            statusEl.innerHTML = isLoading ? 
                '<span class="loading"></span>' + message : message;
        }

        function clearOutputs() {
            document.getElementById('thinkingOutput').innerHTML = '';
            document.getElementById('answerOutput').innerHTML = '';
            updateStatus('输出已清空');
            
            if (currentEventSource) {
                currentEventSource.close();
                currentEventSource = null;
            }
        }

        function appendToOutput(elementId, text, className = '') {
            const output = document.getElementById(elementId);
            const span = document.createElement('span');
            span.className = className;
            span.textContent = text;
            output.appendChild(span);
            output.scrollTop = output.scrollHeight;
        }

        function getTask() {
            const task = document.getElementById('taskInput').value.trim();
            if (!task) {
                alert('请输入任务描述');
                return null;
            }
            return task;
        }

        function disableButtons(disabled) {
            document.getElementById('streamBtn').disabled = disabled;
            document.getElementById('fluxBtn').disabled = disabled;
            document.getElementById('normalBtn').disabled = disabled;
        }

        // SSE 流式输出
        function executeStream() {
            const task = getTask();
            if (!task) return;

            clearOutputs();
            disableButtons(true);
            updateStatus('正在执行流式输出...', true);
            isThinking = true;

            // 关闭之前的连接
            if (currentEventSource) {
                currentEventSource.close();
            }

            currentEventSource = new EventSource(`/api/agent/solve-stream?task=${encodeURIComponent(task)}`);

            // 处理不同类型的SSE事件
            currentEventSource.addEventListener('start', function(event) {
                updateStatus('开始处理任务...', true);
                appendToOutput('thinkingOutput', event.data + '\n', 'thinking');
            });

            currentEventSource.addEventListener('thinking', function(event) {
                appendToOutput('thinkingOutput', event.data, 'thinking');
            });

            currentEventSource.addEventListener('thinking_complete', function(event) {
                isThinking = false;
                updateStatus('思考完成，生成最终答案...', true);
                appendToOutput('thinkingOutput', event.data + '\n', 'thinking');
            });

            currentEventSource.addEventListener('answer', function(event) {
                appendToOutput('answerOutput', event.data, 'answer');
            });

            currentEventSource.addEventListener('complete', function(event) {
                updateStatus('✅ 任务完成');
                disableButtons(false);
                currentEventSource.close();
                currentEventSource = null;
            });

            currentEventSource.addEventListener('error', function(event) {
                appendToOutput('thinkingOutput', event.data + '\n', 'error');
                updateStatus('❌ 执行出错');
                disableButtons(false);
                currentEventSource.close();
                currentEventSource = null;
            });

            // 通用消息处理器（处理未分类的事件）
            currentEventSource.onmessage = function(event) {
                console.log('收到未分类的SSE消息:', event);
                // 如果没有特定的事件类型，默认添加到思考过程
                if (event.data && event.data.trim()) {
                    appendToOutput('thinkingOutput', event.data + '\n', 'thinking');
                }
            };

            currentEventSource.onerror = function(event) {
                console.error('SSE错误:', event);
                appendToOutput('thinkingOutput', '连接错误或中断\n', 'error');
                updateStatus('❌ 连接错误');
                disableButtons(false);
                currentEventSource.close();
                currentEventSource = null;
            };
        }

        // Flux 流式输出
        async function executeFlux() {
            const task = getTask();
            if (!task) return;

            clearOutputs();
            disableButtons(true);
            updateStatus('正在执行简化流式输出...', true);

            try {
                const response = await fetch(`/api/agent/solve-flux?task=${encodeURIComponent(task)}`, {
                    headers: {
                        'Accept': 'text/event-stream'
                    }
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const reader = response.body.getReader();
                const decoder = new TextDecoder();

                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;

                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n');

                    for (const line of lines) {
                        if (line.trim()) {
                            if (line.startsWith('🤖') || line.includes('开始处理任务')) {
                                appendToOutput('thinkingOutput', line + '\n', 'thinking');
                            } else if (line.includes('✅') && line.includes('任务完成')) {
                                updateStatus('✅ 任务完成');
                                appendToOutput('answerOutput', line + '\n', 'answer');
                            } else if (line.startsWith('❌')) {
                                appendToOutput('thinkingOutput', line + '\n', 'error');
                                updateStatus('❌ 执行出错');
                            } else {
                                appendToOutput('answerOutput', line, 'answer');
                            }
                        }
                    }
                }

                updateStatus('✅ 任务完成');
            } catch (error) {
                console.error('Flux错误:', error);
                appendToOutput('thinkingOutput', `错误: ${error.message}\n`, 'error');
                updateStatus('❌ 执行出错');
            } finally {
                disableButtons(false);
            }
        }

        // 传统方式
        async function executeNormal() {
            const task = getTask();
            if (!task) return;

            clearOutputs();
            disableButtons(true);
            updateStatus('正在执行传统方式...', true);

            try {
                const response = await fetch(`/api/agent/solve?task=${encodeURIComponent(task)}`);
                const result = await response.text();

                appendToOutput('thinkingOutput', '使用传统同步方式执行任务...\n', 'thinking');
                appendToOutput('answerOutput', result, 'answer');

                updateStatus('✅ 任务完成');
            } catch (error) {
                console.error('传统方式错误:', error);
                appendToOutput('thinkingOutput', `错误: ${error.message}\n`, 'error');
                updateStatus('❌ 执行出错');
            } finally {
                disableButtons(false);
            }
        }

        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 添加示例任务
            const examples = [
                "分析一个Java类的代码质量，给出改进建议",
                "生成一个Python脚本来读取CSV文件并进行数据分析",
                "创建一个简单的Spring Boot REST API示例",
                "写一个正则表达式来验证邮箱地址"
            ];
            
            const randomExample = examples[Math.floor(Math.random() * examples.length)];
            document.getElementById('taskInput').placeholder = `例如：${randomExample}`;
        });

        // 页面卸载时关闭连接
        window.addEventListener('beforeunload', function() {
            if (currentEventSource) {
                currentEventSource.close();
            }
        });
    </script>
</body>
</html>
